package com.imooc.files.controller;

import com.imooc.api.controller.files.FileUploaderControllerApi;
import com.imooc.api.controller.user.BaseControllerApi;
import com.imooc.exception.GraceException;
import com.imooc.files.resource.FileResource;
import com.imooc.files.service.UploaderService;
import com.imooc.grance.result.GraceJsonResult;
import com.imooc.grance.result.ResponseStatusEnum;
import com.imooc.pojo.bo.NewAdminBO;
import com.imooc.utils.FileUtils;
import com.imooc.utils.extend.AliImageReviewUtils;
import com.mongodb.client.gridfs.GridFSBucket;
import com.mongodb.client.gridfs.GridFSFindIterable;
import com.mongodb.client.gridfs.model.GridFSFile;
import com.mongodb.client.model.Filters;
import com.mysql.cj.util.Base64Decoder;
import org.apache.commons.lang3.StringUtils;
import org.bson.types.ObjectId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 *
 * @auther Levi
 * @Date: 2021/03/18/9:53
 * @Description:
 */
@RestController
public class FileUploaderController extends BaseControllerApi implements FileUploaderControllerApi {
    private static Logger logger =  LoggerFactory.getLogger(FileUploaderController.class);
    @Autowired
    private UploaderService uploaderService;
    @Autowired
    private FileResource fileResource;
    @Autowired
    private AliImageReviewUtils aliImageReviewUtils;
    @Autowired
    private GridFSBucket gridFSBucket;
    private static final String FAILED_IMAGE = "https://imooc-news-devs.oss-cn-hangzhou.aliyuncs.com/image/utils/5cce12973f48ee285889697f3bc1afb9.jpeg";

    @Override
    public GraceJsonResult uploadFace(String userId, MultipartFile file) throws Exception {
        System.out.println("host: ------"+fileResource.getHost());
        String path = "";
        //对文件判空
        if (file != null) {
            String fileName = file.getOriginalFilename();
            //对文件名判空
            if (StringUtils.isNotBlank(fileName)) {
                String[] fileNameArr = fileName.split("\\.");
                //获取文件的扩展名
                String suffix = fileNameArr[fileNameArr.length - 1];
                //判断文件格式是否支持
                if (!"jpg".equalsIgnoreCase(suffix)
                  &&!"jpeg".equalsIgnoreCase(suffix)
                  &&!"png".equalsIgnoreCase(suffix)) {
                    return GraceJsonResult.errorCustom(ResponseStatusEnum.FILE_FORMATTER_FAILD);
                }
            /*      //调用FastDFS的service方法
            path = uploaderService.uploadFdfs(file, suffix);*/

                //调用阿里的oss接口的service方法
                path = uploaderService.uploadOss(file,userId,suffix);
                System.out.println("host: ------"+fileResource.getHost());

            }else{
            return GraceJsonResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_NULL_ERROR);
        }
        }else{
            return GraceJsonResult.errorCustom(ResponseStatusEnum.FILE_UPLOAD_NULL_ERROR);
        }
        logger.info("path: "+path);
        //生成带host的图片最终路径
        String finalPath = "";
        if (StringUtils.isNotBlank(path)) {
            finalPath = fileResource.getOssHost() + path;
        }
        //使用阿里的内容审核Api，后期要收费，所以注释掉
//        return GraceJsonResult.ok(doAliyunImage(finalPath));
        return GraceJsonResult.ok(finalPath);
    }

    /**
     * 判断如果有base64的字符串则先上传图片，上传后得到faceId再传到后端
     * @param newAdminBO
     * @return
     * @throws Exception
     */
    @Override
    public GraceJsonResult uploadToGridFS(NewAdminBO newAdminBO) throws Exception{
//        System.out.println("img64: "+newAdminBO.getImg64());
        //获得base64字符串
        String img64 = newAdminBO.getImg64();
        //将base64字符串转换为字节数组
        byte[] bytes = new BASE64Decoder().decodeBuffer(img64.trim());
        //将将字节数组转换为字节输入流
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        //获得文件的id
        ObjectId fileId = gridFSBucket.uploadFromStream(newAdminBO.getUsername() +
                ".png", inputStream);
        //得到的faceId然后传到后端
        String faceId = fileId.toString();
        return GraceJsonResult.ok(faceId);
    }

    @Override
    public void readInGridFS(String faceId, HttpServletRequest request,
                                        HttpServletResponse response) throws Exception {
        //1.判断faceId为不为空
        if (StringUtils.isBlank(faceId) || "null".equalsIgnoreCase(faceId)) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }
        //2.从GridFS中获取文件信息
        File file = readGridFSByFaceId(faceId);
        FileUtils.downloadFileByStream(response, file);
    }

    @Override
    public GraceJsonResult readFaceInGridFS(String faceId, HttpServletRequest request,
                                            HttpServletResponse response) throws Exception {
        File file = readGridFSByFaceId(faceId);
        String bace64face = FileUtils.fileToBase64(file);
        return GraceJsonResult.ok(bace64face);
    }

    @Override
    public GraceJsonResult uploadSomeFiles(String userId, MultipartFile[] files) throws Exception {
        //1.对获取的files判空
        List<String> fileList = new ArrayList<>();
        if (files != null&&files.length>0) {
            for (MultipartFile file : files) {
                String fileName = file.getOriginalFilename();
                //对文件名判空
                if (StringUtils.isNotBlank(fileName)) {
                    String[] fileNameArr = fileName.split("\\.");
                    //获取文件的扩展名
                    String suffix = fileNameArr[fileNameArr.length - 1];
                    //判断文件格式是否支持
                    if (!"jpg".equalsIgnoreCase(suffix)
                            &&!"jpeg".equalsIgnoreCase(suffix)
                            &&!"png".equalsIgnoreCase(suffix)) {
                        continue;
                    }
            /*      //调用FastDFS的service方法
            path = uploaderService.uploadFdfs(file, suffix);*/

                    //调用阿里的oss接口的service方法
                    String path = uploaderService.uploadOss(file,userId,suffix);
                    String finalPath = "";
                    if (StringUtils.isNotBlank(path)) {
                         finalPath = fileResource.getOssHost() + path;
                    }
                    fileList.add(finalPath);
                }else{
                    continue;
                }
            }
//            logger.info("path: "+path);
            //生成带host的图片最终路径

            //使用阿里的内容审核Api，后期要收费，所以注释掉
//        return GraceJsonResult.ok(doAliyunImage(finalPath));

            }
        return GraceJsonResult.ok(fileList);
        }


    /**
     * 调用阿里云的内容审核
     * @param finalPath
     * @return
     */
    private String doAliyunImage(String finalPath) {
        boolean result = false;
        try {
            result = aliImageReviewUtils.reviewImage(finalPath);
            if (!result) {
                //失败了返回一个审核失败的图片给前端
                return FAILED_IMAGE;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return finalPath;
    }

    private File readGridFSByFaceId(String faceId) throws FileNotFoundException {
        //根据faceid获取的可能是一个集合
        GridFSFindIterable gridFSFiles = gridFSBucket.find(Filters.eq("_id", new ObjectId(faceId)));
        //只要第一个
        GridFSFile gridFSFile = gridFSFiles.first();
        //判空
        if (gridFSFile == null) {
            GraceException.display(ResponseStatusEnum.FILE_NOT_EXIST_ERROR);
        }
        String filename = gridFSFile.getFilename();
        System.out.println("filename: " + filename);
        //通过文件输入流把文件存到本地
        File fileTem = new File(FILE_PATH);
        if (!fileTem.exists()) {
            fileTem.mkdirs();
        }
        String finalFilePath = FILE_PATH +"/"+ filename;
        File file = new File(finalFilePath);
        //根据文件对象创建一个输出流
        OutputStream outputStream = new FileOutputStream(file);
        //使用gridfs把图片下载道本地
        gridFSBucket.downloadToStream(new ObjectId(faceId),outputStream);
        return file;
    }
}
